home *** CD-ROM | disk | FTP | other *** search
/ Experimental BBS Explossion 3 / Experimental BBS Explossion III.iso / c / pcw.zip / MENUS.DOC < prev    next >
Text File  |  1991-12-29  |  19KB  |  431 lines

  1. ----+L---1----+----2----+----3----+----4----+----5----+----6----+----7----J----8
  2.  
  3.  
  4.                               The PC Windows Menus
  5.  
  6.          PC  Windows includes functions for pop-up and a Lotus 1-2-3   type 
  7.      menu.    The discussion of the menus is seperate because they  require 
  8.      some  explanation of their set-up.   The menu functions were built  to 
  9.      take advantage of the way C treats arrays and pointers similarly.   If 
  10.      you  are  learning C for the first time the way the menus in  PCW  are 
  11.      established   may seem a bit arcane,   but if you have  patience   and 
  12.      study  the examples you will learn a valuable lesson about pointers to 
  13.      arrays of structures. 
  14.  
  15.          To  begin,   you will find the structure definitions for  the  PCW 
  16.      menus  in a file called MENU.H.    When you browse the definitions  do  
  17.      not  be  alarmed or put off,   we are going to explain them by way  of 
  18.      example for both kinds of menus.   To start,  we are going to create a  
  19.      pop-up  menu  because it is the simpler of the two PCW menus and  will 
  20.      pave the way for the more complex stacked Lotus menu. 
  21.  
  22.  
  23.                                  The Pop-Up Menu
  24.  
  25.          If  you have used PCs for any length of time you have  undoubtedly 
  26.      run  across  the  venerable pop-up menu.   They are everywhere  in  PC 
  27.      applications,   and  with  PCW  you  can  now  put  them  in  your   C 
  28.      applications.  The pop-up menus in PCW are window oriented which means 
  29.      you  can create the pop-up on the screen accept the input from it  and 
  30.      remove  it  from the video display when you are ready to.   Since  the 
  31.      menu  is in a window this implies window functions in PCW are used  to 
  32.      create  and  manage the window.   This means when you make a  call  to 
  33.      create  the pop-up menu with the makepmenu()  function that  you  will 
  34.      have to supply information about the window the menu is to operate in.  
  35.      For  example,  the window dimensions,  the window colors,  the  border 
  36.      colors,  the title , and the title color.  This is easily accomplished 
  37.      with  C  structures.   We simply initialize some structures  with  the 
  38.      information  about the window and pass pointers to these structures to 
  39.      the menu functions where all of the work is done.  For pop-up menus in 
  40.      PCW we will be concerned with three structure definitions. 
  41.  
  42.  
  43.                                Building an Example
  44.  
  45.  
  46.          If  you  look  in the MENU.H file you will  notice  the  following 
  47.      structure definition. 
  48.  
  49.      typedef struct {
  50.         char  select_key;
  51.         char  *item;
  52.      }PMNUFLDS;
  53.      
  54.          This  structure  definition  is  used to define  the  pop-up  menu 
  55.      options  and a value that uniquely identifies an option.   For example 
  56.      you may want to create menu with four options,  1. Delete, 2. Add,  3. 
  57.      Change,  and E.  Exit.   To do this with the PCW pop-up menu you would 
  58.      simply create and initialize an array of type PMNUFLDS like this. 
  59.  
  60.      static PMNUFLDS poptions[] = {
  61.         { '1', "1. Delete "},
  62.         { '2', "2. Add    "},
  63.         { '3', "3. Change "},
  64.         { 'E', "E. Exit   "},
  65.         {  0,  (char *) 0}
  66.      };
  67.  
  68.      The  above  example creates and initializes an array of structures  of 
  69.      type  PMNUFLDS.   This array will become the options used in the  menu 
  70.      later on.   Notice the last line of the example and how the two fields 
  71.      are  intialized with NULL values.   This is an old idea in C.   It  is 
  72.      used to mark the end of the array since the array could be any size. 
  73.  
  74.      Now   that we have the options of the menu defined we need to tell the  
  75.      menu functions  some information about the window it will use to  show  
  76.      the  options   and  accept  input from.     Again,    looking  at  the 
  77.      structures  in  MENU.H  you  will  notice  the  following  structure 
  78.      definition. 
  79.  
  80.      typedef struct {
  81.         MENU_WND   pwnd;
  82.         int        bar_pos;
  83.         PMNUFLDS   *plist;
  84.      }PMNUTYPE;
  85.  
  86.      We  need to initialize a structure of PMNUTYPE with values and pass  a 
  87.      pointer  to this structure to the pop-up menu functions.   Looking  at 
  88.      the  members of this structure we see that we have our  PMNUFLDS  list 
  89.      with  the  array  of menu options created above,  and  we  can  easily 
  90.      declare the integer, but what is this MENU_WND stuff?  Quite simply it 
  91.      is another structure used to declare information about the window such 
  92.      as  its  boundaries,   color,   border type and so on.    Look at  the 
  93.      MENU.H file again and review the MENU_WND structure. 
  94.  
  95.      typedef struct menu_wnd {
  96.         WNDPTR *wnd;                            /* Window pointer */
  97.         int    urow,ucol,lrow,lcol;             /* Window coordinates */
  98.         int    fcolor, bcolor;                  /* Window color */
  99.         int    btype, bfclr,bbclr;              /* Border type & color */
  100.         char   *title;                          /* The title */
  101.         int    tvloc, thloc, tfclr, tbclr;      /* Title pos & color */
  102.         int    cfclr, cbclr;                    /* Select bar color */
  103.      }MENU_WND;
  104.      
  105.      Now  to  finish this example lets declare and initialize the  PMNUTYPE 
  106.      structure to our program. 
  107.  
  108.      PMNUTYPE pmenu = {
  109.         NULL,                           /* Initial Window Pointer */
  110.         13, 20, 20, 60,                 /* Window boundaries */
  111.         BLACK, LIGHTGRAY,               /* Window Color */
  112.         DOUBLEALL,RED,LIGHTGRAY,        /* Border type and border color */
  113.         " Main Pop-up Menu ",           /* Menu title */
  114.         TOP,MIDDLE,BLUE,LIGHTGRAY,      /* Title location & color */
  115.         WHITE,BLUE,                     /* Select Bar color */
  116.         0,                              /* Initial bar position */
  117.         poptions                        /* Pointer to array of options */
  118.      }
  119.      
  120.      Whew!   That's a lot of information,   but considering all of the work 
  121.      PCW  is  going  to do with this information  your work  is  worth  the 
  122.      effort.   Now that we have everything declared we can create the  menu 
  123.      and  then  accept input from it using two  function  makepmenu()   and 
  124.      pmenuinput().  Lets explain the operation of these two functions.  The 
  125.      makepmenu() function will accept a pointer value to data type PMNUTYPE 
  126.      and  create  the window,  and the menu and return to  your  program  a 
  127.      pointer of type WNDPTR (a handle to a window).  If the Mouse driver is 
  128.      present and has been initialized with init_mouse()  makepmenu()   will 
  129.      turn  on the mouse for use in menu input.   The pmenuinput()  function 
  130.      will,  again,  accept a pointer to type PMNUTYPE and accept input from 
  131.      the keyboard.  It will interpret the arrow keys, tab keys, mouse,  and 
  132.      the enter key.   Futhermore,  the select characters you defined in the 
  133.      PMNUFLDS structure are also active when pmenuinput()  is invoked.  For 
  134.      example  if  you  pressed '1'  at  the  keyboard  pmenuinput()   would 
  135.      highlight  the  Delete option and return the '1'   character  to  your 
  136.      program  where you could do with it as you please.   Needless to  say, 
  137.      you should call makepmenu() before you call pmenuinput(). 
  138.  
  139.                                A Complete Example
  140.  
  141.      Finally  putting  it  all  together we can  give  a  complete  working 
  142.      example. 
  143.      
  144.      #include <stdio.h>
  145.      #include <pcwproto.h>
  146.      #include <menu.h>
  147.  
  148.      /* Declare the menu options */
  149.  
  150.      static PMNUFLDS poptions[] = {
  151.         { '1', "1. Delete "},
  152.         { '2', "2. Add    "},
  153.         { '3', "3. Change "},
  154.         { 'E', "E. Exit   "},
  155.         {  0,  (char *) 0}
  156.      };
  157.  
  158.      /* Declare and initialize window info */
  159.  
  160.      PMNUTYPE pmenu = {
  161.         NULL,                           /* Initial Window Pointer */
  162.         9, 25, 14, 55,                  /* Window boundaries */
  163.         BLACK, LIGHTGRAY,               /* Window Color */
  164.         DOUBLEALL,RED,LIGHTGRAY,        /* Border type and border color */
  165.         " Main Pop-up Menu ",           /* Menu title */
  166.         TOP,MIDDLE,BLUE,LIGHTGRAY,      /* Title location & color */
  167.         WHITE,BLUE,                     /* Select Bar color */
  168.         0,                              /* Initial bar position */
  169.         poptions                        /* Pointer to array of options */
  170.      };
  171.      
  172.      void main(void) {
  173.  
  174.         int i = 0;
  175.         WNDPTR *menuwnd;
  176.         static char *selections[] = {
  177.            "Delete    ",
  178.            "Add       ",
  179.            "Change    "
  180.         };
  181.  
  182.         init_mouse();                     /* Initialize Mouse */
  183.         menuwnd = makepmenu(&pmenu);      /* Create Pop-up menu */
  184.         while (i != 'E' && i != 27) {     /* Do until exit or ESC */
  185.            i = pmenuinput(&pmenu);        /* Get return value from menu */
  186.            switch(i) {                    /* Make a decision */
  187.               case '1' :
  188.               case '2' :
  189.               case '3' :
  190.                  i -= 49;
  191.                  qputs(25,CENTER,WHITE,BLACK,selections[i]);
  192.                  break;
  193.               default  : break;
  194.            }
  195.         }
  196.         if (mpresent) hide_mouse();        /* Hide mouse if home */
  197.         menuwnd = wpop(menuwnd);           /* Remove the menu window */
  198.      }
  199.      
  200.      That was easy!  Just a couple of more things about the menu functions.  
  201.      When  accepting  input from a menu the ESC key will always  return  to 
  202.      your program with a value of 27  (the ESC key value)  where you can do 
  203.      with  it what you will.   In the above example it was used to exit the 
  204.      loop  and terminate the program.   Also the right Mouse key is treated 
  205.      as  though it were an ESC key,  and BOTH Mouse keys are treated as the 
  206.      enter  key,   and  finally  the LEFT Mouse key is  used  to  select  a 
  207.      particular item from the menu. 
  208.  
  209.  
  210.                                 The Picklist Menu
  211.  
  212.      The  Picklist  Menu is very similar to the Pop-Up Menu with one  minor 
  213.      exception:    it does not require a list of type PMNUFLDS.    It  does 
  214.      require,  however, an array of pointers to character strings which act 
  215.      as the options.  And instead of returning a selection key the Picklist 
  216.      menu  returns  a  subscript value to the character  string  which  was 
  217.      chosen.  Again, we will explain by way of a working example. 
  218.  
  219.      If you again look into the MENU.H file you will find a structure 
  220.      declaration like the one below:
  221.  
  222.      typedef struct pick_list {
  223.           MENU_WND  twnd;
  224.           char      **list;
  225.           int       bar_pos, offset;
  226.      }PICKLIST;
  227.  
  228.      As before,  the MENU_WND member of this structure is another structure 
  229.      that will be used to contain information about the size, location, and 
  230.      color  of  the window that will be used for this  menu.    The  **list 
  231.      member  field  is  a  pointer to an array  of  pointers  to  character 
  232.      strings.  These strings will be the actual options for this menu.  The 
  233.      bar_pos  field  is initialized to the beginning bar  position  in  the 
  234.      menu,  and the offset value is initialized to the first option in  the 
  235.      list.    Usually the bar_pos and offset values are intialized to  zero 
  236.      when  the  menu  is  first created.   Now a working  examples  of  the 
  237.      Picklist menu: 
  238.      
  239.      #include <stdio.h>
  240.      #include "pcwproto.h"
  241.      #include "menu.h"
  242.  
  243.      static char *selections[] = {
  244.         "Methodology",
  245.         "Word Processors",
  246.         "C Compiler",
  247.         "Pascal Compiler",
  248.         "3270 Emulation",
  249.         "Communications",
  250.         "COBOL Compiler",
  251.         "MASM",
  252.         NULL
  253.      };
  254.  
  255.      static PICKLIST plmenu =  {
  256.         NULL,
  257.         15, 30, 19, 50, BLACK,LIGHTGRAY,          /* Window Parms */
  258.         2, RED,LIGHTGRAY,                         /* Border Parms */
  259.         " Main Menu ",TOP,MIDDLE,BLUE,LIGHTGRAY,  /* Title  Parms */
  260.         WHITE,BLUE,                               /* Select Bar color  */
  261.         selections,                               /* pointer to menu list */
  262.         0,0                                       /* bar position offset */
  263.      };
  264.  
  265.      int main ( void ) {
  266.  
  267.        int i = 0;
  268.        int mxr, mxc;
  269.        WNDPTR *wnd;
  270.  
  271.        chk_video_state(&mxr,&mxc);               /* Get max rows & cols */
  272.        init_mouse();                             /* turn on mouse if there */
  273.        wnd = make_pick_list(&plmenu);            /* Make a popup window */
  274.        while (i != -1) {                         /* Do until Esc */
  275.           i = get_pick_list(&plmenu);            /* Get Menu return value */
  276.           if ( i == -1 ) continue;               /* ESC was pressed */
  277.           if ( mpresent ) hide_mouse();          /* Hide the mouse */
  278.           qhchar(22,1,BLACK,BLACK,32,80);        /* Clear msg line */
  279.           qputs(22,99,RED,7,selections[i]);      /* Write the choice */
  280.           if (mpresent) show_mouse();            
  281.        }
  282.        if (mpresent) hide_mouse();               /* Hide the mouse */
  283.        wnd     = wpop(wnd);                      /* Get rid of menu */
  284.        return 0;                                 /* And go home */
  285.      }
  286.  
  287.      
  288.  
  289.                                  The Lotus Menu
  290.                                                
  291.      
  292.      Setting  up  the Lotus menu is very similar to setting up  the  pop-up 
  293.      menu.    The only thing that is different about the Lotus menu is that 
  294.      more than one menu can be stacked into a window at one time,  and this 
  295.      requires some special setting up.  Looking at the structures in MENU.H 
  296.      you will see the following definition. 
  297.  
  298.      typedef struct {
  299.         char  select_key;
  300.         int   select_col;
  301.         char  *item;
  302.         char  *item_msg;
  303.      }LMNUFLDS;
  304.  
  305.      This  structure  is  similar  to the PMNUFLDS  structure  in  that  it 
  306.      contains  the  select_key member and the *item member,   but  two  new 
  307.      members  have been added.   The select_col member is used  to  specify 
  308.      which  column  in  the window you want this  option  to  begin.    The 
  309.      *item_msg member is a short description of what this option does. 
  310.  
  311.      Now  creating the options list for the menu is almost the same as  for 
  312.      the pop-up menu.  Just look.
  313.      
  314.      LMNUFLDS menu1[] = {
  315.         { 'A', 2, "Add", "Add an Entry to Database"},
  316.         { 'C', 7, "Change", "Change a Database Entry"},
  317.         { 'D', 15,"Delete", "Delete a Database Entry"},
  318.         { NULL, NULL, NULL, NULL}
  319.      }; 
  320.      
  321.      LMNUFLDS menu2[] = {
  322.         { 'P', 2, "Purge", "Purge the Workfile"},
  323.         { 'S', 10,"Send",  "Send Electronic Mail"},
  324.         { 'E', 15,"Exit",  "Exit the Program"}, 
  325.         {  NULL,NULL,NULL,NULL }
  326.      };
  327.      
  328.      LMNUFLDS *menulist[] = {menu1, menu2, NULL}; 
  329.      
  330.      Let's take a look at what we have done here.  First we have created an 
  331.      array  of  data structure type LMNUFLDS and have  called  it  menu1[].  
  332.      Notice that it is NULL terminated.   Now since more than one menu  can 
  333.      be  stacked  into  one window we create the second menu  and  call  it 
  334.      menu2[].   Now,  how do we tie all these menus together?   Simple,  we 
  335.      create  an array of pointers of type LMNUFLDS and initialize  it  with 
  336.      the beginning addresses of each of the menus and make sure that it too 
  337.      is  NULL terminated.  If you wanted more menus in one window then  you 
  338.      would  just  define  the menu options just as we did for  menu1[]  and 
  339.      menu[]2   and  assign its beginning address to an array  of  pointers.  
  340.      This way you can stack as many menus into one window as you like. 
  341.      
  342.      Now  to  complete  this  example  we must  declare  and  initialize  a 
  343.      structure  defined  as  LMNUTYPE.    Looking at MENU.H we  see  it  is 
  344.      declared as follows. 
  345.      
  346.      typedef struct {
  347.         MENU_WND   lwnd;
  348.         int        bar_pos, wnd_pos;
  349.         LMNUFLDS   **llist;
  350.      }
  351.      
  352.      Let's explain a little bit here.  First MENU_WND you have already been 
  353.      introduced to.  It was used for the Pop-up menu too.   The two members 
  354.      bar_pos  and wnd_pos will be initialized to a value to indicate  which 
  355.      menu  to  start  with  and which option  the  selection  bar  will  be 
  356.      positioned on.  Finally,  the **llist member is a pointer to a pointer 
  357.      and  will  be initialized with the beginning address of our  array  of 
  358.      pointers  to arrays of type LMNUFLDS.   Whew,  got that?   Okay,   the 
  359.      complete example. 
  360.      
  361.      #include <stdio.h>
  362.      #include <pcwproto.h>
  363.      #include <menu.h>
  364.      
  365.      static LMNUFLDS menu1[] = {
  366.         { 'A', 2, "Add",    "Add an Entry to Database"},
  367.         { 'C', 17,"Change", "Change a Database Entry"},
  368.         { 'D', 33,"Delete", "Delete a Database Entry"},
  369.         { NULL, NULL, NULL, NULL}
  370.      }; 
  371.      
  372.      static LMNUFLDS menu2[] = {
  373.         { 'P', 2, "Purge", "Purge the Workfile"},
  374.         { 'S', 18,"Send",  "Send Electronic Mail"},
  375.         { 'E', 35,"Exit",  "Exit the Program"},
  376.         {  NULL,NULL,NULL,NULL }
  377.      };
  378.      
  379.      static LMNUFLDS *menulist[] = {menu1, menu2, NULL}; 
  380.      
  381.      static LMNUTYPE lmenu = {
  382.          NULL,
  383.          10, 20, 13, 60,
  384.          BLUE, LIGHTGRAY,
  385.          DOUBLEALL,RED,LIGHTGRAY,
  386.          " The Lotus ",
  387.          TOP,MIDDLE,BLACK,LIGHTGRAY,
  388.          WHITE,BLUE,
  389.          0,0,menulist
  390.      };
  391.  
  392.      static char *selections[] = {
  393.         "Add    ", "Change ",
  394.         "Delete ", "Purge  ",
  395.         "Send   "
  396.      };
  397.  
  398.      void main(void) {
  399.  
  400.         int    i = 0;
  401.         int    index = 0;
  402.         WNDPTR *menuwnd;
  403.  
  404.         init_mouse();
  405.         menuwnd = makelmenu(&lmenu);
  406.         while (i != 'E' && i != 27) {
  407.            i = lmenuinput(&lmenu);
  408.            switch(i) {
  409.                case 'A' : index = 0; break;
  410.                case 'C' : index = 1; break;
  411.                case 'D' : index = 2; break;
  412.                case 'P' : index = 3; break;
  413.                case 'S' : index = 4; break;
  414.                case 27  :
  415.                case 'E' : continue;
  416.            }
  417.            qputs(25,CENTER,WHITE,BLACK,selections[index]);
  418.         }
  419.         if (mpresent) hide_mouse();
  420.         menuwnd = wpop(menuwnd);
  421.      } 
  422.      
  423.  
  424.      Well,  there they are.  Explanations and examples.  I  know this seems 
  425.      to be a lot of work for a couple of menus,  but they can significantly 
  426.      enhance the way your programs look and feel to the user not to mention 
  427.      making you look like a genius in the process.  After a little work the 
  428.      menus  almost  seem effortless.   So have fun and enjoy and make  some 
  429.      great looking screens and menus with PC windows. 
  430.  
  431.